import {useCallback, useContext, useEffect, useRef, useState} from "react";
import {
	AsyncPageSelectSearchParam, getAllTypesOfMetasByPageCode,
} from "@/biz-components/claim-items/components";
import * as CommonDataSource from '@/common-data-source';
import {DetailContext} from "@/biz-components/claim-items/components/DetailContext";
import { plus } from '@ey-utils/utils/numberPrecision';
import {CommonTable, CellInput, CommonValidator} from "@/biz-components/claim-items/components-v2";
import {useSelectOptions} from "@/common-data-source";
import {useField, useForm} from "@formily/react";
import {Field} from "@formily/core/lib/models";
import moment from "moment";
import {SelectAssistant1} from "@/biz-components/claim-items/collection-manual/SelectAssistant1";
import {
	SelectSpecialAccountFlag
} from "@/biz-components/claim-items/collection-manual/SelectSpecialAccountFlag";

/**
 * @author DongPing
 * 2022/1/13 10:00
 *
 * 收款池-手工认领明细
 *
 * */

const PAGE_CODE = 'ClaimInfoB_MC_L';

export function CollectionManual(props: {
	value: any[],
	onChange: (value: any[]) => void,
	// 门店，用于查询下拉选项
	shop: string,
	validateError: boolean
}) {
	const {value = [], onChange, shop = ''} = props;

	function onClickAdd() {
		// XYL-1385 反记账字段和印花税应税标识字段，勾选框组件，勾选后，字段值保存为X
		props.onChange(value.concat([{
			// antiAcctng: 'X',
			// stampTaxMark: 'X',
			referDate: moment().format('YYYY-MM-DD')
		}]))
	}
	const [metas, setMetas] = useState<any[]>([]);
	useEffect(function () {
		getAllTypesOfMetasByPageCode(PAGE_CODE)
			.then((data) => {
				setMetas(data.tableColumnMetas.concat([
					{
						key: 'referDate',
						props: {},
						label: '参考日期'
					}
				]))
			})
	}, []);

	function onDelete(record: any) {
		props.onChange(value.filter((item) => item!==record));
	}


	const queryAAACallback = useCallback((p: AsyncPageSelectSearchParam) => {
		return CommonDataSource.others.queryAccountingSubjectOptionsPage(p, shop);
	}, [shop])

	const querySupplierCallback = useCallback((p: AsyncPageSelectSearchParam) => {
		return CommonDataSource.shop.queryShopSuppliersPage(p, shop, true);
	}, [shop]);

	const queryCustomerCallback = useCallback((p: AsyncPageSelectSearchParam) => {
		return CommonDataSource.shop.queryShopCustomersPage(p, props.shop);
	}, [props.shop])

	const queryEmployeeSuppliersCallback = useCallback((p: AsyncPageSelectSearchParam) => {
		return CommonDataSource.shop.queryShopEmployeeSuppliersPage(p, props.shop);
	}, [props.shop]);
	const querySaleBarSuppliersCallback = useCallback((p: AsyncPageSelectSearchParam) => {
		return CommonDataSource.shop.queryShopSaleBarSuppliersPage(p, props.shop);
	}, [props.shop]);

	const taxRateOptions = CommonDataSource.useSelectOptions<string>(CommonDataSource.dictionary.queryDictionaryForSelect, 'TAX_CODE');

	// // 利润中心下拉数据
	// const profitOptions = CommonDataSource.useSelectOptions<void>(CommonDataSource.others.queryProfitCenterOptions);
	//
	// // 成本中心下拉数据
	// const costCenterOptions = CommonDataSource.useSelectOptions<void>(CommonDataSource.others.queryCostCenterOptions);

	const queryProfitOptionsCallback = useCallback((p:AsyncPageSelectSearchParam) => {
		// return CommonDataSource.others.queryProfitCenterPage(p, props.shop);
	}, [props.shop]);

	// post code options
	const postCodeOptions = useSelectOptions(CommonDataSource.others.queryAccountCodes);

	const detailMode = useContext(DetailContext);

	const validateTableRef = useRef<() => boolean>(null);

	const field = useField<Field>();
	const form = useForm();
	useEffect(function () {
		field.setValidator(() => {
			if(validateTableRef.current && !validateTableRef.current()) {
				return {type: 'error', message: '认领明细填写有误'}
			} else if(calcLoanAmount(value) !== calcLendAmount(value)) {
				return {type: 'error', message: '借项金额不等于贷项金额'}
			} else {
				let claimedAmt = Number(form.getValuesIn('claimedAmt'));
				if(calcLendAmount(value) > claimedAmt) {
					return {type: 'error', message: '借项金额不能大于可认领金额'}
				}
				return null;
			}
		});
	}, [validateTableRef, value]);


	const reasonCodeOptions = useSelectOptions((s) => {
		// return CommonDataSource.others.queryReasonCodeOptions(s)
	}, props.shop);
	// const specialCodeOptions = useSelectOptions((s) => {
	// 	return CommonDataSource.others.querySpecialFlagOptions(s)
	// }, '');

	/**
	 * 查询特别总账标识需要的账户类型啊
	 * 客户代码选择了值，账户类型就传D、供应商代码选择了值，账户类型就传K
	 *
	 * http://jira.ecsphere.net:9080/browse/XYL-1423
	 * 2022/3/8 17:47
	 * 当员工代码有值或柜组编码有值时，也当有供应商，查特别总账标识时，账户类型就传K
	 * */
	function getAccountType(record: any = {}): 'K' | 'D' | '' {
		if(record.customerCode) {
			return 'D'
		} else if(record.supplierCode || record.employeeId || record.deptCode) {
			return 'K'
		} else {
			return ''
		}
	}

	return (
		<div>
			<CommonTable
				pageCode={PAGE_CODE}
				metaArr={metas}
				value={value}
				onChange={onChange}
				detailMode={detailMode}
				claimItemsInvalid={true}
				validateFunctionRef={validateTableRef}
				addOperation
				onAdd={onClickAdd}
				deleteOperation
				onDelete={onDelete}
				deleteDisabled={(record) => record.__defaultRow}
				columnsOptionArr={[
					{
						name: 'postCode',
						component: [CellInput.Selector, {dataSource: postCodeOptions, valueInLabel: true} as CellInput.SelectorExtraProps],
						disabled: (record) => record.__defaultRow,
						renderDetail: (value: any) => (postCodeOptions.find((item) => item.value === value)?.name || '')
					},
					{
						name: 'acctgSubj',
						disabled: (record) => record.__defaultRow,
						component: [CellInput.AsyncPageSelect, {search: queryAAACallback, valueAsSelectResult: true} as CellInput.AsyncPageSelectExtraProps],
						relationForNameAttribute: 'acctgSubjName'
					},
					{
						name: 'voucherCrncyAmt',
						component: [CellInput.NumberInput, {}],
						disabled: (record) => record.__defaultRow,
						validator: (v: any) => CommonValidator.numberRequired(v)
					},
					{
						name: 'supplierCode',
						component: [CellInput.AsyncPageSelect, {search: querySupplierCallback, valueAsSelectResult: true} as CellInput.AsyncPageSelectExtraProps],
						relationForNameAttribute: 'supplierName',
						disabled: (r: any) => (r.customerCode || r.employeeId || r.deptCode)
					},
					{
						name: 'customerCode',
						component: [CellInput.AsyncPageSelect, {search: queryCustomerCallback, valueAsSelectResult: true} as CellInput.AsyncPageSelectExtraProps],
						relationForNameAttribute: 'customerName',
						disabled: (r: any) => (r.supplierCode || r.employeeId || r.deptCode)
					},
					{
						name: 'employeeId',
						component: [CellInput.AsyncPageSelect, {search: queryEmployeeSuppliersCallback, valueAsSelectResult: true} as CellInput.AsyncPageSelectExtraProps],
						relationForNameAttribute: 'employeeName',
						disabled: (r: any) => (r.supplierCode || r.customerCode || r.deptCode),
						hide: true
					},
					{
						name: 'employeeName',
						hide: true
					},
					{
						name: 'deptCode',
						component: [CellInput.AsyncPageSelect, {search: querySaleBarSuppliersCallback, valueAsSelectResult: true} as CellInput.AsyncPageSelectExtraProps],
						disabled: (r: any) => (r.supplierCode || r.customerCode || r.employeeId),
						hide: true
					},
					{
						name: 'specialGlId',
						component: [SelectSpecialAccountFlag, (record: any) => ({accountType: getAccountType(record), shop: shop})],
						//renderDetail: (value, record) => <SelectSpecialAccountFlag value={value} onChange={() => null} detailMode disabled accountType={getAccountType(record)} shop={shop}/>,
						onRowChange: (row: any) => {row.zzcoals = ''}
					},
					{
						name: 'causeCode',
						component: [CellInput.Selector, {dataSource: reasonCodeOptions, showSearch: true, valueInLabel: true, style: {minWidth: '250px'}} as CellInput.SelectorExtraProps],
						//renderDetail: (v) => reasonCodeOptions.find((item) => item.value === v)?.name || ''

					},
					{
						name: 'taxRateVal',
						component: [CellInput.Selector, {dataSource: taxRateOptions, valueInLabel: true} as CellInput.SelectorExtraProps],
						//renderDetail: (value: any) => (taxRateOptions.find((item) => item.value === value)?.name || '')
					},
					{
						name: 'zzcoals',
						component: [SelectAssistant1, (record: any) =>  ({specialAccountFlag: record.specialGlId, valueInLabel: true, showSearch: true})],
						//renderDetail: (v: any, record: any) => <SelectAssistant1 value={v} onChange={() => {}} disabled={false} detailMode specialAccountFlag={record.specialGlId}/>

					},
					{
						name: 'spmtyAcctgB',
						//component: [SelectAssistant1, (record: any) =>  ({specialAccountFlag: record.specialGlId, valueInLabel: true, showSearch: true})],
						component: [CellInput.TextInput, {}],
						//renderDetail: (v: any, record: any) => <SelectAssistant1 value={v} onChange={() => {}} disabled={false} detailMode specialAccountFlag={record.specialGlId}/>

					},
					{
						name: 'profitCenter',
						component: [CellInput.AsyncPageSelect, {search: queryProfitOptionsCallback, valueAsSelectResult: true} as CellInput.AsyncPageSelectExtraProps],
						relationForNameAttribute: 'profitCenterTxt',
					},
					{
						name: 'costCenter',
						component: [CellInput.AsyncPageSelect, {search: queryProfitOptionsCallback, valueAsSelectResult: true}  as CellInput.AsyncPageSelectExtraProps],
						relationForNameAttribute: 'costCenterTxt',
					},
					{
						name: 'txt',
						component: [CellInput.TextInput, {}]
					},
					{
						name: 'antiAcctng',
						component: [CellInput.Checkbox, {}],
						onRowChange: (record: any) => {
							if(record.antiAcctng) {
								record.antiAcctng = 'X'
							} else {
								record.antiAcctng = undefined;
							}
						},
						renderDetail: (value) => <CellInput.CheckboxDetail checked={!!value}/>
					},
					{
						name: 'stampTaxMark',
						component: [CellInput.Checkbox, {}],
						onRowChange: (record: any) => {
							if(record.stampTaxMark) {
								record.stampTaxMark = 'X'
							} else {
								record.stampTaxMark = undefined;
							}
						},
						renderDetail: (value) => <CellInput.CheckboxDetail checked={!!value}/>
					}

				]}
			/>

			<div>
				<p>
					借项金额：{calcLendAmount(value)} &nbsp;&nbsp;&nbsp;  贷项金额：{calcLoanAmount(value)}
				</p>
			</div>
		</div>
	)
}
CollectionManual.calcLendAmount = calcLendAmount;
CollectionManual.calcLoanAmount = calcLoanAmount;

/**
 * 计算借项金额
 * */
function calcLendAmount(data: any[] = []): number {
	let total = 0;
	for(const item of data) {
		if(!CommonDataSource.others.checkAccountCodeIsLend(item.postCode)) continue;
		let n = Number(item.voucherCrncyAmt);
		if(isNaN(n)) continue;
		total = plus(total, n);
	}
	return total;
}

/**
 * 计算贷项金额
 * */
function calcLoanAmount(data: any[] = []): number {
	let total = 0;
	for(const item of data) {
		if(CommonDataSource.others.checkAccountCodeIsLend(item.postCode)) continue;
		let n = Number(item.voucherCrncyAmt);
		if(isNaN(n)) continue;
		total = plus(total, n);
	}
	return total;
}

